package com.uam.core.lk.utils;

public class GisUtils {

    private static double EARTH_RADIUS = 6378.137;

    /**
     *
     * @Title: getDistance
     * @author: zhangxj
     * @date:   2018年12月11日 下午1:41:33
     * @Description: 获取两个经纬度之间的距离
     * @param: @param lat1 维度1
     * @param: @param lng1 经度1
     * @param: @param lat2 纬度2
     * @param: @param lng2 经度2
     * @param: @return
     * @return: double  距离，米
     * @throws
     */
    public static double getDistance(double lat1, double lng1, double lat2,
                                     double lng2) {
        double s = 0d;
        try {
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);
            s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                    * Math.pow(Math.sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.round(s * 10000d) / 10000d;
            s = s * 1000;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            s = 0d;
        }
        return s;
    }

    /**
     *
     * @Title: getDistanceByStr
     * @author: zhangxj
     * @date:   2019年1月11日 下午6:26:08
     * @Description: 根据两个字符串的经纬度获取两点之间的距离
     * @param: @param lat1Str
     * @param: @param lng1Str
     * @param: @param lat2Str
     * @param: @param lng2Str
     * @param: @return
     * @return: double
     * @throws
     */
    public static double getDistanceByStr(String lat1Str, String lng1Str, String lat2Str,
                                          String lng2Str) {
        double s = 0d;
        if (lat1Str == null || "".equals(lat1Str)
            || lng1Str == null || "".equals(lng1Str)
            || lat2Str == null || "".equals(lat2Str)
            || lng2Str == null || "".equals(lng2Str)) {
            return s;
        }
        try {
            double lat1 = Double.parseDouble(lat1Str);
            double lng1 = Double.parseDouble(lng1Str);
            double lat2 = Double.parseDouble(lat2Str);
            double lng2 = Double.parseDouble(lng2Str);
            double radLat1 = rad(lat1);
            double radLat2 = rad(lat2);
            double a = radLat1 - radLat2;
            double b = rad(lng1) - rad(lng2);
            s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
            s = s * EARTH_RADIUS;
            s = Math.round(s * 10000d) / 10000d;
            s = s * 1000;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            s = 0d;
        }
        return s;
    }

    // 计算方位角,正北向为0度，以顺时针方向递增
    public static double computeAzimuth(double lon1, double lat1, double lon2, double lat2) {
        double result = 0.0;

        int ilat1 = (int) (0.50 + lat1 * 360000.0);
        int ilat2 = (int) (0.50 + lat2 * 360000.0);
        int ilon1 = (int) (0.50 + lon1 * 360000.0);
        int ilon2 = (int) (0.50 + lon2 * 360000.0);

        lat1 = Math.toRadians(lat1);
        lon1 = Math.toRadians(lon1);
        lat2 = Math.toRadians(lat2);
        lon2 = Math.toRadians(lon2);

        if ((ilat1 == ilat2) && (ilon1 == ilon2)) {
            return result;
        } else if (ilon1 == ilon2) {
            if (ilat1 > ilat2)
                result = 180.0;
        } else {
            double c = Math
                .acos(Math.sin(lat2) * Math.sin(lat1) + Math.cos(lat2)
                    * Math.cos(lat1) * Math.cos((lon2 - lon1)));
            double A = Math.asin(Math.cos(lat2) * Math.sin((lon2 - lon1))
                / Math.sin(c));
            result = Math.toDegrees(A);
            if ((ilat2 > ilat1) && (ilon2 > ilon1)) {
            } else if ((ilat2 < ilat1) && (ilon2 < ilon1)) {
                result = 180.0 - result;
            } else if ((ilat2 < ilat1) && (ilon2 > ilon1)) {
                result = 180.0 - result;
            } else if ((ilat2 > ilat1) && (ilon2 < ilon1)) {
                result += 360.0;
            }
        }
        return result;
    }

    public static void main(String[] args) {
        double distance = getDistance(39.9188232421875, 116.444091796875,
            39.913330078125, 116.455078125);
        System.out.println("距离" + distance / 1000.0 + "公里");
        System.out.println("距离" + String.format("%.2f", distance / 1000.0) + "公里");
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    private GisUtils() {

    }
}
